<?php
/**
 * 
 * @author Shrey
 *
 */
abstract class AbstractSearchableBehavior extends ModelBehavior
{
	/**
	 *	Default values for Behavior.
	 *	filterField : name of model property where filter configuration is stored
	 *	defaultBoolean : operator two be used with statement ie OR,NOT,AND
	 *	defaultOperator : operator for comparing values in sql satatement.
	 *	notificationMethod : name of model method to be called for getting records with saved searches 
	 * 	@var unknown_type
	 */
	var $_default = array(
		'filterField'=>"searchFilter",
		'defaultBoolean'=> "AND",
		"defaultOperator" =>"=",
		'notificationMethod'=>"getSearchMatches"
	);
	var $config = array();
	
	/**
	 * 
	 * @param $model
	 * @param $config
	 */
	function setup($model,$config)
	{
		$this->config[$model->alias]  = am($config,$this->_default);
	}
	
	function createCondition($model,$filterName,$values)
	{
		$filterConfig  = $this->getFilterConfiguration($model);
		$conditions = array();
		if(isset($filterConfig[$filterName]))
		{
			foreach($filterConfig[$filterName] as $filterName => $config)
			{
				if(strpos($filterName,'.')=== false)
				{
					$filterName = $model->alias.'.'.$filterName;
				}

				$value = Set::extract($filterName,$values);
				if(is_null($value)==false && $value !=='')
				{
					$field = $filterName;
					if(isset($config['field']))
						$field = $config['field'];
					if(strpos($field,'.') === false)
						$field = $model->alias.'.'.$field;
					$boolean = $this->config[$model->alias]['defaultBoolean'];
					if(isset($config['boolean']))
						$boolean = $config['boolean'];
					$operator = $this->config[$model->alias]['defaultOperator'];
					if(isset($config['operator']))
					{
						$operator = $config['operator'];
					}
					$callback = null;
					if(isset($config['callback']) && strlen($config['callback']) > 0)
						$callback = $config['callback'];
					$condition = $this->getOperatorCondition($model,$field,$value,$operator,$callback);
					//we intianed condition array a operator only when a avalid condition array is returned
					//or else we would get mysql error.
					if($condition)
					{
						if(!isset($conditions[$boolean]))
							$conditions[$boolean] = array();
						$conditions[$boolean] = am($conditions[$boolean],$condition);
					}
				}
			}
		}
		return $conditions;
	}
	function getOperatorCondition(AppModel$model,$field,$value,$operator,$callback)
	{
		$operator = up($operator);
		$condition = array();
		if($callback)
		{
			$condition = $model->dispatchMethod($callback,array($field,$value,$operator));
		}else
		{
			switch($operator)
			{
				case "LIKE":
				case "like":
					$condition = array($field." LIKE" => "%$value%"); 
					break;
				case "<":
				case "<=":
				case ">=":
				case ">":
					$condition = array($field." ".$operator => $value);
					break;
				default :
					$condition = array($field => $value);
			}
		}
				
		return $condition;
	}
	function addFilter($model,$filterName,$configuration)
	{
		
	}
	
	function getFilterConfiguration($model)
	{
		if(isset($model->{$this->config[$model->alias]['filterField']}))
		{
			return $model->{$this->config[$model->alias]['filterField']};
		}
		return array();
	}
	
	function beforeFind($model,$query)
	{
		return $query;
	}
	
	function getSavedSearchMethod($model)
	{
		$modelFnName = $this->config[$model->alias]['notificationMethod'] ;
		return $modelFnName;
	}
}
?>